import React, { useState } from 'react';
import toast from 'react-hot-toast';

type Status = 'editing' | 'saving' | 'showing';

type RenderProps<T> = {
  value: T;
  setValue: (value: T) => void;
  status: Status;
  onAsyncSave: (value: T) => Promise<void>;
  onCancel: () => void;
  onEdit: () => void;
};

type EditableProps<T> = {
  initValue: T;
  onSave: (value: T) => Promise<void> | void;
  children: (props: RenderProps<T>) => React.ReactNode;
};

// TODO: 数据校验

export default function Editable<T>({ onSave, initValue, children }: EditableProps<T>) {
  const [status, setStatus] = useState<Status>('showing');
  const [value, setValue] = useState<T>(initValue);

  const saveAsync = async (value: T) => {
    setStatus('saving');
    try {
      await onSave(value);
      setStatus('showing');
    } catch (err) {
      // TODO: 更细致地处理错误
      toast.error('保存失败');
      console.error('保存失败', err);
      setStatus('editing');
    }
  };

  return (
    <>
      {children({
        status,
        value,
        setValue,
        onAsyncSave: saveAsync,
        onCancel: () => {
          setStatus('showing');
          setValue(initValue);
        },
        onEdit: () => setStatus('editing'),
      })}
    </>
  );
}
